﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace Tools.Http
{
    /// <summary>
    /// http基础服务
    /// </summary>
    public static class HttpService
    {
        /// <summary>
        /// GET请求数据
        /// </summary>
        /// <param name="url">接口地址</param>
        /// <param name="headers">请求头</param>
        /// <param name="callBack">回调函数</param>
        /// <returns></returns>
        public static async Task HttpGet(string url, Dictionary<string, string> headers = null, Action<ResultModel> callBack = null)
        {
            try
            {
                HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, url);
                
                if (headers != null && headers.Count > 0)
                {
                    foreach (KeyValuePair<string, string> item in headers)
                    {
                        request.Headers.Add(item.Key, item.Value);
                    }
                }
                using (HttpClient client = new HttpClient())
                {
                    client.DefaultRequestHeaders.ExpectContinue = false;
                    HttpResponseMessage response = await client.SendAsync(request);
                    string responseBody = await response.Content.ReadAsStringAsync();

                    if (response.IsSuccessStatusCode)
                    {
                        ResultModel result = ResultModel.Success((long)response.StatusCode, responseBody);
                        callBack?.Invoke(result);
                    }
                    else
                    {
                        ResultModel result = ResultModel.Fail((long)response.StatusCode, responseBody);
                        callBack?.Invoke(result);
                    }
                }
            }
            catch (Exception ex)
            {
                ResultModel result = ResultModel.Fail(0, ex.Message);
                Debug.WriteLine(ex.ToString());
                callBack?.Invoke(result);
            }
        }

        /// <summary>
        /// POST请求数据
        /// </summary>
        /// <param name="url">接口地址</param>
        /// <param name="formData">表单数据</param>
        /// <param name="headers">请求头</param>
        /// <param name="callBack">回调函数</param>
        /// <returns></returns>
        public static async Task HttpPost(string url, Dictionary<string, string> formData, Dictionary<string, string> headers = null, Action<ResultModel> callBack = null)
        {
            try
            {
                FormUrlEncodedContent content = new FormUrlEncodedContent(formData);
                HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url) { Content = content };
                request.Headers.Add("Content-Type", "application/x-www-form-urlencoded");

                // 添加请求头
                if (headers != null && headers.Count > 0)
                {
                    foreach (KeyValuePair<string, string> item in headers)
                    {
                        request.Headers.Add(item.Key, item.Value);
                    }
                }

                using (HttpClient client = new HttpClient())
                {
                    client.DefaultRequestHeaders.ExpectContinue = false;
                    HttpResponseMessage response = await client.SendAsync(request);
                    string responseBody = await response.Content.ReadAsStringAsync();

                    if (response.IsSuccessStatusCode)
                    {
                        ResultModel result = ResultModel.Success((long)response.StatusCode, responseBody);
                        callBack?.Invoke(result);
                    }
                    else
                    {
                        ResultModel result = ResultModel.Fail((long)response.StatusCode, responseBody);
                        callBack?.Invoke(result);
                    }
                }
            }
            catch (Exception ex)
            {
                ResultModel result = ResultModel.Fail(0, ex.Message);
                callBack?.Invoke(result);
            }
        }

        /// <summary>
        /// POST请求数据
        /// </summary>
        /// <param name="url">接口地址</param>
        /// <param name="postData">json格式参数</param>
        /// <param name="headers">请求头</param>
        /// <param name="callBack">回调函数</param>
        /// <returns></returns>
        public static async Task HttpPost(string url, string postData, Dictionary<string, string> headers = null, Action<ResultModel> callBack = null)
        {
            try
            {
                StringContent content = new StringContent(postData, Encoding.UTF8, "application/json");

                HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url) { Content = content };

                // 添加请求头
                if (headers != null && headers.Count > 0)
                {
                    foreach (KeyValuePair<string, string> item in headers)
                    {
                        request.Headers.Add(item.Key, item.Value);
                    }
                }
                using (HttpClient client = new HttpClient())
                {
                    client.DefaultRequestHeaders.ExpectContinue = false;
                    HttpResponseMessage response = await client.SendAsync(request);
                    string responseBody = await response.Content.ReadAsStringAsync();

                    if (response.IsSuccessStatusCode)
                    {
                        ResultModel result = ResultModel.Success((long)response.StatusCode, responseBody);
                        callBack?.Invoke(result);
                    }
                    else
                    {
                        ResultModel result = ResultModel.Fail((long)response.StatusCode, responseBody);
                        callBack?.Invoke(result);
                    }
                }
            }
            catch (Exception ex)
            {
                ResultModel result = ResultModel.Fail(0, ex.Message);
                callBack?.Invoke(result);
            }
        }
    }
}


/// <summary>
/// 返回结果
/// </summary>
public class ResultModel : ResultModel<string>
{
    /// <summary>
    /// 构造函数
    /// </summary>
    public ResultModel(bool result, long code, string data, string message) : base(result, code, data, message)
    {
    }

    /// <summary>
    /// 成功
    /// </summary>
    public new static ResultModel Success(long code, string data = null, string message = null)
    {
        return new ResultModel(true, code, data, message);
    }

    /// <summary>
    /// 失败
    /// </summary>
    public new static ResultModel Fail(long code, string message)
    {
        return new ResultModel(false, code, null, message);
    }
}

/// <summary>
/// 返回结果
/// </summary>
public class ResultModel<T>
{
    /// <summary>
    /// 结果
    /// </summary>
    public bool Result { get; set; }

    /// <summary>
    /// 代码
    /// </summary>
    public long Code { get; set; }

    /// <summary>
    /// 数据
    /// </summary>
    public T Data { get; set; }

    /// <summary>
    /// 消息
    /// </summary>
    public string Message { get; set; }

    /// <summary>
    /// 构造函数
    /// </summary>
    public ResultModel(bool result, long code, T data, string message)
    {
        Result = result;
        Code = code;
        Data = data;
        Message = message;
    }

    /// <summary>
    /// 成功
    /// </summary>
    public static ResultModel<T> Success(long code, T data, string message = null)
    {
        return new ResultModel<T>(true, code, data, message);
    }

    /// <summary>
    /// 失败
    /// </summary>
    public static ResultModel<T> Fail(long code, string message)
    {
        return new ResultModel<T>(false, code, default(T), message);
    }
}
